home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / comm / comm2 / hdrbb112.lha / HBBS / Source / Node / Node_Serial.c < prev   
C/C++ Source or Header  |  1996-11-19  |  9KB  |  379 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5.  
  6. #include <exec/exec.h>
  7. #include <dos/dos.h>
  8.  
  9. #include <devices/serial.h>
  10. #include <hardware/cia.h>
  11.  
  12. #include <clib/exec_protos.h>
  13. #include <clib/alib_protos.h>
  14. #include <clib/dos_protos.h>
  15.  
  16. #define NOTMAIN
  17.  
  18. #define ClrSignal(s)  SetSignal(0,s)
  19.  
  20. #include "/common/types.h"
  21. #include "/common/defines.h"
  22. #include "/common/structures.h"
  23. #include "/common/strings.h"
  24. #include "/common/errors.h"
  25. #include "/common/shared_protos.h"
  26. #include "/common/Files.h"
  27.  
  28. #include "Node_Input_protos.h"
  29. #include "Node_Console_protos.h"
  30. #include "/library/hbbscommon_protos.h"
  31. #include "/library/hbbscommon_pragmas.h"
  32. #include "nodelibrary/hbbsnode_protos.h"
  33. #include "nodelibrary/hbbsnode_pragmas.h"
  34.  
  35. extern struct NodeData *N_ND;
  36. extern struct BBSGlobalData *BBSGlobal;
  37. extern struct Library *HBBSCommonBase;
  38. extern struct Library *HBBSNodeBase;
  39.  
  40.  
  41. void CleanupSerial( void )
  42. {
  43.   if (!N_ND->NodeDevice.SysopNode)
  44.   {
  45.     if (N_ND->SerBuffer)
  46.     {
  47.       if (N_ND->SerPort)
  48.       {
  49.         if (N_ND->SerWrite)
  50.         {
  51.           if (N_ND->SerOPEN)
  52.           {
  53.             if (N_ND->SerRead)
  54.             {
  55.               AbortSerRead(); // will only abort id request submitted..
  56.               FreeVec(N_ND->SerRead);
  57.             }
  58.             CloseDevice((struct IORequest*)N_ND->SerWrite);
  59.             N_ND->SerOPEN=FALSE;
  60.           }
  61.           DeleteExtIO((struct IORequest*)N_ND->SerWrite);
  62.         }
  63.         DeletePort(N_ND->SerPort);
  64.       }
  65.       FreeVec(N_ND->SerBuffer);
  66.     }
  67.   }
  68.   N_ND->SerOK=FALSE;
  69. }
  70.  
  71. void SerReset( void )
  72. {
  73.   // this routine reads in all waiting data from the serial port and then dumps it!
  74.   UBYTE *mem;
  75.   ULONG bytes;
  76.  
  77.   if (bytes=SerQueryData())
  78.   {
  79.     if (mem=AllocVec(bytes,MEMF_PUBLIC))
  80.     {
  81.       WaitSerReadBlock(mem,bytes); // *C* ooh naughty.. should really have somekind of wait() here..
  82.       FreeVec(mem);
  83.     }
  84.   }
  85. }
  86.  
  87. V_BOOL OpenSerial( void )
  88. {
  89.   N_ND->SerWaiting=FALSE;
  90.   N_ND->SerOK=FALSE;
  91.   N_ND->SerOPEN=FALSE;
  92.   if (!N_ND->NodeDevice.SysopNode)
  93.   {
  94.     if (N_ND->SerBuffer=AllocVec(DEF_SERBUFLEN,MEMF_PUBLIC))
  95.     {
  96.       N_ND->SerBufferLen=DEF_SERBUFLEN;
  97.       if (N_ND->SerPort=CreatePort(0,0))
  98.       {
  99.         if (N_ND->SerWrite = (struct IOExtSer *) CreateExtIO(N_ND->SerPort,(ULONG)sizeof(struct IOExtSer)))
  100.         {
  101.  
  102. /* For Shared Mode XPR
  103.  
  104.           if (N_ND->NodeDevice.NullModemCable)
  105.           {
  106.             N_ND->SerWrite->io_SerFlags       = SERF_SHARED;
  107.           }
  108.           else
  109.           {
  110.             N_ND->SerWrite->io_SerFlags       = SERF_SHARED|SERF_7WIRE|SERF_XDISABLED|SERF_RAD_BOOGIE;
  111.           }
  112. */
  113.           if (!N_ND->NodeDevice.NullModemCable)
  114.           {
  115.             N_ND->SerWrite->io_SerFlags       = SERF_7WIRE|SERF_XDISABLED|SERF_RAD_BOOGIE;
  116.           }
  117.  
  118.           if (!(OpenDevice((STRPTR)N_ND->NodeDevice.SerialDevice,(ULONG)N_ND->NodeDevice.SerialUnit,(struct IORequest *)N_ND->SerWrite,0L) ))
  119.           {
  120.             N_ND->SerOPEN=TRUE;
  121.             // kill data waiting..
  122.             N_ND->SerWrite->IOSer.io_Command  = CMD_RESET;
  123.             DoIO((struct IORequest *)N_ND->SerWrite);
  124.  
  125.  
  126.             // setup port with correct baud rate etc..
  127.             N_ND->SerWrite->IOSer.io_Command  = SDCMD_SETPARAMS;
  128.             N_ND->SerWrite->io_SerFlags       |= SERF_XDISABLED;
  129.             N_ND->SerWrite->io_Baud           = N_ND->NodeDevice.SerialBaud;
  130.             DoIO((struct IORequest *)N_ND->SerWrite);
  131.  
  132.  
  133.             if (N_ND->SerRead = (struct IOExtSer*)AllocVec(sizeof(struct IOExtSer),MEMF_PUBLIC) )
  134.             {
  135.               // duplicate data...
  136.               memcpy(N_ND->SerRead,N_ND->SerWrite,sizeof(struct IOExtSer));
  137.               SerReset();
  138.               N_ND->SerOK=TRUE;
  139.               return(TRUE);
  140.             }
  141.           }
  142.           else HBBS_DoErrorMessage(EMSG_NODEVICE,N_ND->NodeNum,NULL);
  143.         }
  144.       }
  145.     }
  146.     CleanupSerial();
  147.   }
  148.   return(FALSE);
  149. }
  150.  
  151. ULONG ModemGetLine( void )
  152. {
  153.   ULONG ReturnedSigs;
  154.   UBYTE CurrentChar[2]={0,0}; // 2 chars, use ¤tchar for null terminated string type..
  155.   ULONG retval=IN_NOTHING; // this must NOT be returned to the caller!!!!!
  156.  
  157.   struct TimerData *TD;
  158.  
  159.   N_ND->CurrentLine[0]=0; // null terminate the string..
  160.  
  161.   if (TD=SubmitTimer(N_ND->NodeTimer,N_ND->NodeDevice.MaxCommandWait,0))
  162.   {
  163.     do
  164.     {
  165.       if (!N_ND->SerWaiting) SendSerReadData();
  166.  
  167.       // we cant use SetupSigs() and WaitAllSigs() because if we are resetting
  168.       // the modem after a LOGIN_LOCAL sersigs is set to 0... :-)
  169.       // *C* add timeout
  170.       N_ND->SerSig=DEF_SERSIG;
  171.       N_ND->TimerSig=DEF_TIMERSIG;
  172.       ReturnedSigs=Wait(N_ND->SerSig | N_ND->TimerSig);
  173.  
  174.       while (HandleSerSigs(ReturnedSigs) && retval==IN_NOTHING)
  175.       {
  176.         // ok, we got some data from somehwere...
  177.  
  178.         CurrentChar[0]=N_ND->IBuffer[0];
  179.  
  180.         if (CurrentChar[0]>=0x20 && CurrentChar[0]!=127) // i.e. not unprintable or a control char..
  181.         {
  182.           strcat(N_ND->CurrentLine,CurrentChar);
  183.         }
  184.         else
  185.         {
  186.           if (CurrentChar[0]=='\n')
  187.           {
  188.             if (strlen(N_ND->CurrentLine)>0) retval=IN_GOTLINE;
  189.           }
  190.         }
  191.       }
  192.  
  193.       if ((retval==IN_NOTHING) && (CheckTimer(N_ND->NodeTimer,TD)))
  194.       {
  195.         TD=NULL;
  196.         retval=IN_TIMEOUT;
  197.       }
  198.     }
  199.     while (retval==IN_NOTHING);
  200.     if (TD) AbortTimer(N_ND->NodeTimer,TD);
  201.  
  202.     if (N_ND->NodeDevice.ModemDebug && N_ND->ConOK)
  203.     {
  204.       ConWriteStr(N_ND->CurrentLine);
  205.       ConWriteStr(str_CRLF);
  206.     }
  207.     if (N_ND->SerWaiting) AbortSerRead();
  208.   }
  209.   return(retval);
  210. }
  211.  
  212. void ModemError(char *command, char *result)
  213. {
  214.   char errstr[2048]; // big enough ?
  215.  
  216.   if (N_ND->NodeDevice.ModemLog)
  217.   {
  218.     sprintf(errstr,"When Sending the command \"%s\" the modem returned \"%s\"",command,result);
  219.  
  220.     HBBS_LogError(N_ND->NodeSettings.ModemLogFile,ERR_GENERAL,errstr,TYPE_WARNING);
  221.   }
  222. }
  223.  
  224. void TurnEchoOn( void )
  225. {
  226.   struct Node *node;
  227.   short retriesleft;
  228.   BOOL Done;
  229.   ULONG result;
  230.  
  231.  
  232.   PutText("\033[37;0m\n");
  233.   for (node=N_ND->NodeDevice.TurnOnEcho->lh_Head;node->ln_Succ;node=node->ln_Succ)
  234.   {
  235.     if (node->ln_Name)
  236.     {
  237.       Done=FALSE;
  238.       retriesleft=N_ND->NodeDevice.EchoRetries;
  239.       do
  240.       {
  241.         if (retriesleft!=N_ND->NodeDevice.EchoRetries)
  242.         {
  243.           ConWriteStr("Retrying Modem...\n\r");
  244.         }
  245.  
  246.         retriesleft--;
  247.         Delay(N_ND->NodeDevice.TurnOnEchoDelay);
  248.         SerReset();
  249.         SerWriteStr(node->ln_Name);
  250.         SerWriteStr(str_CRLF);
  251.         if (result=ModemGetLine()==IN_GOTLINE)
  252.         {
  253.           // ok, got some input..
  254.  
  255.           if (stricmp(node->ln_Name,N_ND->CurrentLine)==0)
  256.           {  // echo is already on, so discard this line and read another line..
  257.             result=ModemGetLine();
  258.           }
  259.           if (result==IN_GOTLINE)
  260.           {
  261.             if (stricmp("OK",N_ND->CurrentLine)==0) Done=TRUE;
  262.           }
  263.         }
  264.       } while (!Done && retriesleft>0);
  265.     }
  266.   }
  267.   SerReset();
  268. }
  269.  
  270. V_BOOL SendModemString(char *str)
  271. {
  272.   ULONG err=1;
  273.   ULONG loop,loop2=N_ND->NodeDevice.CommandRetries;
  274.   BOOL linemismatch;
  275.  
  276.   do
  277.   {
  278.  
  279.     // this loop sends the command to the modem and wait for the characters to
  280.     // be echoed back.  if we don't get back what we send we try it again!
  281.  
  282.     loop=N_ND->NodeDevice.CommandRetries;
  283.     do
  284.     {
  285.       Delay(N_ND->NodeDevice.DelayBetweenCmds);
  286.       SerReset(); //clear all crap before we send our new string..
  287.       SerWriteStr(str);
  288.       SerWriteStr(str_CRLF);
  289.       ModemGetLine();
  290.       if (linemismatch=(stricmp(str,N_ND->CurrentLine)!=0 ? TRUE : FALSE))
  291.       {
  292.         TurnEchoOn();
  293.       }
  294.     } while (loop-- && linemismatch);
  295.  
  296.     // right if we are here then we know we're gonna get a blank line and a timeout
  297.     // or OK OR ERROR..  if we don't get OK then we retry the command...
  298.     ModemGetLine();
  299.  
  300.   } while (loop2-- && stricmp(N_ND->CurrentLine,"OK")!=0 && (err=stricmp(N_ND->CurrentLine,"ERROR"))==0);
  301.   if (!err) ModemError(str,N_ND->CurrentLine);
  302.   return(err);
  303. }
  304.  
  305. void OffHook( void )
  306. {
  307.   if (N_ND->NodeSettings.UseDevice)
  308.   {
  309.     SendModemString(N_ND->NodeDevice.OffHookString);
  310.   }
  311. }
  312.  
  313. void ReOpenSerial( void )
  314. {
  315.   V_SMALLNUM loop=N_ND->NodeDevice.ReOpenRetries;
  316.   if (!N_ND->NodeDevice.SysopNode)
  317.   {
  318.     CleanupSerial();
  319.  
  320.     while (loop-- && N_ND->SerOK==FALSE)
  321.     {
  322.       Delay(N_ND->NodeDevice.ReOpenDelay);
  323.       OpenSerial();
  324.     }
  325.  
  326.     if (!N_ND->SerOK)
  327.     {
  328.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,ESTR_NOSERIAL,TYPE_CRITICAL);
  329.     }
  330.   }
  331. }
  332.  
  333. void HangUp( void )
  334. {
  335.   struct Node *node;
  336.  
  337.   if (!N_ND->NodeSettings.UseDevice)
  338.   {
  339.     if (!N_ND->NodeDevice.NullModemCable)
  340.     {
  341.       if (!N_ND->NodeDevice.DropDTRHangup)
  342.       {
  343.         for (node=N_ND->NodeDevice.CommandModeString->lh_Head;node->ln_Succ;node=node->ln_Succ)
  344.         {
  345.           if (node->ln_Name) SerWriteStr(node->ln_Name);
  346.         }
  347.         SendModemString(N_ND->NodeDevice.HangUpString);
  348.       }
  349.       ReOpenSerial();
  350.       OffHook();
  351.     }
  352.     else
  353.     {
  354.       ReOpenSerial();
  355.     }
  356.   }
  357. }
  358.  
  359. V_BOOL InitModem( void )
  360. {
  361.   struct Node *node;
  362.  
  363.   if (N_ND->NodeSettings.UseDevice)
  364.   {
  365.     if (N_ND->NodeDevice.ModemDebug && N_ND->ConOK)
  366.     {
  367.       ConWriteStr("Initialising Modem...\n\r");
  368.     }
  369.  
  370.     TurnEchoOn();
  371.     for (node=N_ND->NodeDevice.ModemInit->lh_Head;node->ln_Succ;node=node->ln_Succ)
  372.     {
  373.       if (node->ln_Name) SendModemString(node->ln_Name);
  374.     }
  375.   }
  376.   return(TRUE);
  377. }
  378.  
  379.